import { ref, computed, nextTick } from 'vue'
import { defineStore, storeToRefs } from 'pinia'
import { getSoundSourceApi, getSongLrcApi } from '@/apis'
import { useSongListStore } from './useSonglistStore'
import unique from '@/utils/unique'

// 按需导出 useAudioStore
export const useAudioStore = defineStore(
  'audioInfo',
  () => {
    // 获取useSongListStore数据和方法
    const songListStores = useSongListStore()
    // 数据-解构 store 的状态，使用 storeToRefs 可以帮助保持响应性
    const { songList } = storeToRefs(songListStores)
    console.log(songList)
    nextTick(() => {})

    // 歌词
    const songLrc = ref([])
    // 获取歌词数据
    const getSongLrc = async (data) => {
      const res = await getSongLrcApi(data)

      songLrc.value = res
      return res
    }

    // 当前歌曲数据
    const songItemInfo = ref({})
    // 当前音频的长度（单位：s）
    const duration = ref(0)
    // 当前音频的播放时间（单位：s）
    const currentTime = ref(0)
    // 是否播放
    const isPlay = ref(false)
    // 播放列表数据
    const playSongList = ref([])
    const songIndex = ref(0)
    // 播放模式
    const playMode = ref(0)
    // 创建音频
    const innerAudioContext = ref(uni.createInnerAudioContext())

    // 音源配置
    const songAudioContext = (item) => {
      // 多次会调用播放新的文件时，提前销毁实例，可避免-99错误

      if (innerAudioContext.value) {
        try {
          innerAudioContext.value.pause()
          innerAudioContext.value.destroy()
          innerAudioContext.value = null
        } catch (e) {
          //TODO handle the exception
        }
      }
      innerAudioContext.value = uni.createInnerAudioContext()
      innerAudioContext.value.volume = 0.5
      innerAudioContext.value.src = item.source

      currentTime.value = 0
      duration.value = 0

      // 设置事件
      // setAudioEvent()
    }

    // 设置音频事件-获取当前时间和总音频时长
    const setAudioEvent = () => {
      const url = `https://fy-musicbox-api.mu-jie.cc/meting/?server=netease&type=url&id=${songItemInfo.value.rid}`
      // innerAudioContext.src =('https://fy-musicbox-api.mu-jie.cc/meting/?server=netease&type=url&id=189602')
      // innerAudioContext.play()
      // 当前音频的播放时间（单位：s）
      currentTime.value = 0
      // 当前音频的长度（单位：s）
      duration.value = 0
      isPlay.value = false

      // 音频进入可以播放状态，但不保证后面可以流畅播放
      innerAudioContext.value.onCanplay(() => {
        // 当前音频的播放时间（单位：s）
        currentTime.value = innerAudioContext.value.currentTime

        // 当前音频的长度（单位：s）
        duration.value = innerAudioContext.value.duration
      })

      // 音频播放事件
      innerAudioContext.value.onPlay(() => {
        // 播放true
        isPlay.value = true
      })

      // 音频暂停事件
      innerAudioContext.value.onPause(() => {
        // 播放true
        isPlay.value = false
      })

      // 音频播放进度更新事件
      innerAudioContext.value.onTimeUpdate((e) => {
        // 当前音频的播放时间（单位：s）
        currentTime.value = innerAudioContext.value.currentTime
      })

      // 音频自然播放结束事件
      innerAudioContext.value.onEnded(() => {
        // 播放false
        isPlay.value = false
        currentTime.value = 0
        // 下一首
        nextSong()
      })

      // innerAudioContext.value.onWaiting(() => {
      //   console.log('wa')
      //   // 当前音频的播放时间（单位：s）
      //   currentTime.value = innerAudioContext.value.currentTime
      //   // 当前音频的长度（单位：s）
      //   duration.value = innerAudioContext.value.duration
      // })

      // 音频完成 seek 操作事件
      // innerAudioContext.value.onSeeked(() => {
      //   // 当前音频的播放时间（单位：s）
      //   currentTime.value = innerAudioContext.value.currentTime
      // })
    }

    // 设置播放
    const setPlay = () => {
      innerAudioContext.value.autoplay = true
      innerAudioContext.value.play()
    }

    // 判断是否存在播放列表
    const isSongList = (arr, item) => {
      let state = false

      arr.forEach((pItem) => {
        pItem.playSelected = false
        // 当前播放歌曲与播放列表存在就直接把状态改为true
        if (pItem.rid === item.rid) {
          console.log('存在了')
          pItem.playSelected = true
          pItem.addList = true
          state = true
        }
      })

      return state
    }

    // 添加歌曲到播放列表
    const addSongPlayList = async (item, type = 1, arr, uname = 'rid') => {
      // type: 1 为之添加播放列表里，不播放
      // type: 2 为之添加播放列表里，且播放
      // 清空播放器信息
      clearAudioInfo()
      // 设置为已添加 true
      item.addList = true
      // type: 1 添加数据
      if (type === 1) item = Object.assign(item, await getSongLrcAtSource(item))
      // 设置当前歌曲信息
      songItemInfo.value = item
      // 传数组还是默认数组
      const nArr = arr ? arr : [...playSongList.value, item]
      const isAdd = isSongList(playSongList.value, item)
      // const text = !isAdd ? '加入播放成功' : '已加入列表'

      // 添加就提示
      if (type === 1) {
        // 显示提示
        uni.$fui.toast('加入播放成功')
      }

      // 去重重新赋值  uname: 根据那个属性名去重
      if (!isAdd) playSongList.value = unique(nArr, uname)
      // 设置歌曲信息
      songAudioContext(item)
    }

    // 在播放列表删除歌曲项
    const delPlaySong = (index) => {
      playSongList.value.splice(index, 1)
    }

    // 当前播放歌曲在播放列表里索引
    const currentSongIndex = computed(() => {
      return playSongList.value.findIndex(
        (item) => songItemInfo.value.rid === item.rid
      )
    })

    // 清空播放列表
    const clearPlayList = () => {
      playSongList.value = []
      songLrc.value = []
      songItemInfo.value = {}
    }

    // 清空播放器数据
    const clearAudioInfo = () => {
      currentTime.value = 0
      duration.value = 0
      songLrc.value = []
      songItemInfo.value = {}
    }

    // 获取歌词和歌曲音源
    const getSongLrcAtSource = async (item) => {
      // 歌曲源地址
      item.source = await getSoundSourceApi(item.rid)
      // 歌词为空执行
      if (item.songLrc.length === 0) {
        // 获取歌词
        item.songLrc = await getSongLrc(item.rid)
      }

      return item
    }

    // 获取当前歌曲播放执行方法
    const songAudioInfo = async (item, index) => {
      songIndex.value = index
      // 歌曲源地址/歌词为空执行
      // 歌曲源地址为空执行
      item.source = `https://fy-musicbox-api.mu-jie.cc/meting/?server=netease&type=url&id=${item.rid}`
      // 设置歌曲源地址/歌词
      // item = Object.assign(item, await getSongLrcAtSource(item))
      // 设置所有播放开关为false
      isSongList(playSongList.value, item)
      // 去重数组重新赋值
      addSongPlayList(item, 2)
      // 播放歌曲
      setSongPlay(item)
    }

    // 设置歌曲信息及播放
    const setSongPlay = (item) => {
      // 设置所有播放开关为false
      isSongList(playSongList.value, item)
      // 设置当前歌曲信息
      songItemInfo.value = item
      // 设置歌曲信息
      songAudioContext(item)
      // 播放
      setPlay()
    }

    // 获取当前歌曲在播放列表下一首、上一首索引函数
    const nextSongIndex = (isAdd) => {
      let index = currentSongIndex.value

      // 判断播放模式
      if (playMode.value === 0) {
        // 是上一首还是下一首
        if (isAdd) {
          index += 1
        } else {
          index -= 1
        }
        // 数组长度和index相等索引0
        if (index >= playSongList.value.length) {
          index = 0
          return index
        }

        // index小于1索引为数组长度
        if (index < 0) {
          index = playSongList.value.length - 1
          return index
        }
        console.log('1-loop--', index)
      } else if (playMode.value === 1) {
        // 随机歌曲索引
        index = Math.floor(Math.random() * playSongList.value.length)
        console.log('2-random--', index)
      } else if (playMode.value === 2) {
        // 单曲索引
        index = currentSongIndex.value
        console.log('3--c-', index)
      }
      console.log('4---', index)
      // 返回索引
      return index
    }

    // 上一首
    const previousSong = () => {
      setSongPlay(playSongList.value[nextSongIndex(false)])
    }

    // 下一首
    const nextSong = () => {
      setSongPlay(playSongList.value[nextSongIndex(true)])
    }

    // 暂停歌曲
    const pauseSong = () => {
      innerAudioContext.value.pause()
    }

    // 播放歌曲
    const playSong = () => {
      innerAudioContext.value.play()
    }

    // 更新歌曲播放时间-跳转到指定位置，单位 s
    const updatedSeek = (time) => {
      currentTime.value = time
      innerAudioContext.value.seek(time)
    }

    // 歌曲播放模式
    const changePlayMode = (type = 0) => {
      // 0: 循环
      // 1: 随机
      // 2: 单曲
      playMode.value = type
    }

    return {
      currentTime,
      duration,
      songItemInfo,
      songLrc,
      playSongList,
      playMode,
      innerAudioContext,
      // 判断是否存在播放列表方法
      isSongList,
      // 获取歌曲信息方法
      songAudioInfo,
      // 切换播放模式方法
      changePlayMode,
      // 添加歌曲到播放列表里方法
      addSongPlayList,
      // 上一首歌曲方法
      previousSong,
      // 下一首歌曲方法
      nextSong,
      // 暂停歌曲方法
      pauseSong,
      // 播放歌曲方法
      playSong,
      // 更新歌曲播放时间方法
      updatedSeek,
      // 删除播放列表对应歌曲项方法
      delPlaySong,
      // 清空播放列表数据方法
      clearPlayList,
    }
  },
  {
    unistorage: true, // 开启后对 state 的数据读写都将持久化
  }
)
